#ifndef COMMON_DOT_H
#define COMMON_DOT_H
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#ifndef NOINLINE
#define NOINLINE __attribute__((noinline))
#endif

typedef void (*TestFunc)();

// @mem start addr of memory
// @size memory size in byte
// @line line number
NOINLINE
void printMemory(void *mem, uint32_t size, int line) {
  printf("Line %d:\n\n", line);
  uint8_t *data = (uint8_t*)mem;
  for (int i = 0; i < size; ++i) {
    printf("%2x ", *(data + i));
    if ((i + 1) % 8 == 0) {
      printf("\n");
    }
  }
  printf("\n");
}

NOINLINE
void setStackAllOnes256bytes() {
  asm volatile("stp	x29, x30, [sp, -304]!");
  asm volatile("add	x29, sp, 0");
  asm volatile("stp x0, x1, [sp, 16]");
  asm volatile("str x2, [sp, 32]");
  asm volatile("add	x0, x29, 48");
  asm volatile("mov	x2, 256");
  asm volatile("mov	w1, 255");
  asm volatile("bl	memset");
  asm volatile("ldp x0, x1, [sp, 16]");
  asm volatile("ldr x2, [sp, 32]");
  asm volatile("ldp	x29, x30, [sp], 304");
  asm volatile("ret");
  // volatile uint8_t data[256];
  // memset((void*)(&data), 0xff, 256);
}

NOINLINE
void runTest(TestFunc func) {
  setStackAllOnes256bytes();
  (*func)();
  printf(" ");  // avoid tail call opt
}

#endif
